#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define ABSOLUTE
#define USING_DUP

char *str1 = "File read and write operation test\n";
char *str2 = "File descriptor copy test\n";
char buffer[100];

int main(int argv, char *argc[])
{
	int fd;
	int new_fd;
	long result;
	
	//设置umask值为0000&0777，创建文件时文件权限为mode&~umask
	umask(0);
	
	//打开文件
	fd = open("./test.txt", O_CREAT|O_TRUNC|O_RDWR, 0777);
	if(fd == -1)
	{
		perror("open");
		return -1;
	}
	
	//写文件
#ifndef ABSOLUTE
	result = write(fd, str1, strlen(str1));
#else
	result = pwrite(fd, str1, strlen(str1), 0);
#endif
	if(result == -1)
	{
		close(fd);
		perror("write");
		return -1;
	}
	printf("File written successfully\r\n");
	
	//读文件
	memset(buffer, 0, sizeof(buffer));
#ifndef ABSOLUTE
	//重定位
	result = lseek(fd, 0, SEEK_SET);
	if(result == -1)
	{
		close(fd);
		perror("lseek");
		return -1;
	}
	result = read(fd, buffer, sizeof(buffer)-1);
#else
	result = pread(fd, buffer, sizeof(buffer)-1, 0);
#endif
	if(result == -1)
	{
		close(fd);
		perror("read");
		return -1;
	}
	
	//校验读写结果
	if(strcmp(str1, buffer) != 0)
	{
		close(fd);
		printf("Check the error\r\n");
		return -1;
	}
	printf("File read successfully\r\n");
	
	//复制文件描述符
#ifndef USING_DUP
	new_fd = dup2(fd, 200);
#else
	new_fd = dup(fd);
#endif
	if(new_fd == -1)
	{
		close(fd);
		perror("dup");
		return -1;
	}
	
	//关闭fd
	close(fd);
	
	//测试new_fd
	if(ftruncate(new_fd, 0) == -1)
	{
		close(new_fd);
		perror("ftruncate");
		return -1;
	}
	result = pwrite(new_fd, str2, strlen(str2), 0);
	if(result == -1)
	{
		close(new_fd);
		perror("pwrite");
		return -1;
	}
	memset(buffer, 0, sizeof(buffer));
	result = pread(new_fd, buffer, sizeof(buffer)-1, 0);
	if(result == -1)
	{
		close(new_fd);
		perror("pread");
		return -1;
	}
	//校验读写结果
	if(strcmp(str2, buffer) != 0)
	{
		close(fd);
		printf("Check the error\r\n");
		return -1;
	}
	printf("Copy file descriptor successfully\r\n");
	
	close(new_fd);
	return 0;
}